<?php

namespace app\admin\controller;

use app\common\controller\AdminBaseController;
use app\common\model\AttachmentModel;
use OSS\OssClient;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use think\Db;
use think\facade\Env;

class UploadController extends AdminBaseController
{

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 上传单张图片
     */
    public function file()
    {
        $opener = $this->request->param('opener');
        if($opener=='ckeditor'){ //ckeditor上传处理
            $file = $this->request->file("upload");
        }else{
            $file = $this->request->file("file");
        }
        $uploadType = config('upload.type');
        switch ($uploadType) {
            case 'local':
                $this->uploadFile($file);
                break;
            case 'alioss':
                $this->uploadAlioss($file);
                break;
            case 'qiniu':
                $this->uploadQiniu($file);
                break;
        }
    }

    /**
     * 上传本地文件
     */
    public function uploadFile($file)
    {
        try{
            $prefix = config("upload.local.prefix");
            $valid = $this->getValid($prefix);
            $info = $file->validate(['size' => $valid['size'], 'ext' => $valid['ext']])->move($valid['upload_path']);
            if ($info) {
                $fileUrl = str_replace(['./', '\\'], '/', $valid['upload_path'] . '/' . $info->getSaveName()); //处理保存路径
                $fileUrl = str_replace(Env::get('ROOT_PATH'), '', $fileUrl);
                $fileInfo = $info->getInfo();
                $data = [
                    'storage' => 'local',
                    'original_name' => $fileInfo['name'],
                    'file_name' => $info->getFilename(),
                    'file_url' => $fileUrl,
                    'file_size' => $info->getSize(),
                    'mimetype' => $info->getMime(),
                    'ext' => $info->getExtension()
                ];
                $this->insertFile($data);
                die(json_encode(['uploaded' => 1, 'fileName' => $data['file_name'],'ext'=>$data['ext'],'originalName'=>$data['original_name'],'url'=>$data['file_url']]));
            } else {
                die(json_encode(['uploaded' => 0, 'error' => ['message'=>$file->getError()]]));
            }
        }catch (\Exception $e){
            die(json_encode(['uploaded' => 0, 'error' =>['message'=>$e->getMessage()]]));
        }
    }

    /**
     * 上传阿里OSS
     */
    public function uploadAlioss($file)
    {
        try{
            $fileInfo = $file->getInfo();
            $prefix = config("upload.alioss.prefix");
            $valid = $this->getValid($prefix);
            //检测文件
            if($file->check(['size' => $valid['size'], 'ext' => $valid['ext']])===false){
                exception($file->getError(),40001);
            };
            $config = config('upload.alioss');
            $fileName = md5(microtime(true).$fileInfo['name']).'.'.$this->getExt($fileInfo['name']);
            $fileUrl = $valid['upload_path'] . '/' . date('Ymd') . "/" . $fileName;
            $parseUrl = parse_url($fileUrl);
            $fileUploadObject = str_replace('/upload','upload',$parseUrl['path']);
            //执行阿里云上传
            $ossClient = new OssClient($config['ak'], $config['sk'], $config['endpoint']);
            $ossClient->uploadFile($config['bucket'], $fileUploadObject, $fileInfo['tmp_name']);
            $data = [
                'storage' => 'alioss',
                'file_name' => $fileName,
                'file_url' => $fileUrl,
                'file_size' => $fileInfo['size'],
                'mimetype' => $fileInfo['type'],
                'ext' => $this->getExt($fileInfo['name'])
            ];
            $this->insertFile($data);
            die(json_encode(['uploaded' => 1, 'fileName' => $data['file_name'],'ext'=>$data['ext'],'originalName'=>$data['original_name'],'url'=>$data['file_url']]));
        }catch (\Exception $e){
            die(json_encode(['uploaded' => 0, 'error' =>['message'=>$e->getMessage()]]));
        }
    }

    /**
     * 上传七牛存储
     */
    public function uploadQiniu($file)
    {
        try{
            $fileInfo = $file->getInfo();
            $prefix = config("upload.qiniu.prefix");
            $valid = $this->getValid($prefix);
            //检测文件
            if($file->check(['size' => $valid['size'], 'ext' => $valid['ext']])===false){
                exception($file->getError(),40001);
            };
            $config = config('upload.qiniu');
            $fileName = md5(microtime(true).$fileInfo['name']).'.'.$this->getExt($fileInfo['name']);
            $fileUrl = $valid['upload_path'] . '/' . date('Ymd') . "/" . $fileName;
            $parseUrl = parse_url($fileUrl);
            $fileUploadObject = str_replace('/upload','upload',$parseUrl['path']);
            //执行七牛上传
            $auth = new Auth($config['ak'], $config['sk']);
            $token = $auth->uploadToken($config['bucket']);
            $uploadMgr = new UploadManager();
            $uploadMgr->putFile($token, $fileUploadObject, $fileInfo['tmp_name']);
            $data = [
                'storage' => 'qiniu',
                'file_name' => $fileName,
                'file_url' => $fileUrl,
                'file_size' => $fileInfo['size'],
                'mimetype' => $fileInfo['type'],
                'ext' => $this->getExt($fileInfo['name'])
            ];
            $this->insertFile($data);
            die(json_encode(['uploaded' => 1, 'fileName' => $data['file_name'],'ext'=>$data['ext'],'originalName'=>$data['original_name'],'url'=>$data['file_url']]));
        }catch (\Exception $e){
            die(json_encode(['uploaded' => 0, 'error' =>['message'=>$e->getMessage()]]));
        }
    }

    /**
     * 插入数据库文件
     */
    public function insertFile($data){
        $dbData = $data;
        $dbData['upload_time'] = time();
        $dbData['admin_id'] = (int)$this->loginInfo['id'];
        AttachmentModel::create($dbData);
    }
    /**
     * 获取文件后缀名
     */
    private function getExt($fileName){
        $pathInfo = pathinfo($fileName);
        return $pathInfo['extension'];
    }
    /**
     * 获取验证规则
     * @param $basePath
     * @return array
     */
    private function getValid($basePath)
    {
        $extType = $this->request->param('ext_type', 'img');
        switch ($extType) {
            case 'img':
                $valid = [
                    'ext' => config('upload.img.ext'),
                    'size' => config('upload.img.size'),
                    'upload_path' => $basePath . '/images'
                ];
                break;
            case 'file':
                $valid = [
                    'ext' => config('upload.file.ext'),
                    'size' => config('upload.file.size'),
                    'upload_path' => $basePath . '/file'
                ];
                break;
            case 'vedio':
                $valid = [
                    'ext' => config('upload.vedio.ext'),
                    'size' => config('upload.vedio.size'),
                    'upload_path' => $basePath . '/vedio'
                ];
                break;
            default:
                exception('ext error!');
                break;
        }
        return $valid;
    }

    /**
     * 文件浏览
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function browse(){
        if($this->request->isAjax()){
            $pageNumber = $this->request->param('pageNumber/d',1); //当前页
            $pageSize = $this->request->param('pageSize/d',20); //每页多少条
            $expType=$this->request->param('ext_type','img'); //筛选类型
            $map = [];
            if($expType!='all'){
                $map[]=['ext','in',config("upload.{$expType}.ext")];
            }
            $data['total'] = Db::table('attachment')->where($map)->count();
            $list = Db::table('attachment')->where($map)->order('upload_time desc')->page($pageNumber,$pageSize)->select();
            $data['rows'] = $list->isEmpty() ? [] : $list->toArray();
            return $data;
        }
        return $this->fetch();
    }
}